package middleware

import (
	"mychat/internal/conf"
	"strings"

	"github.com/gin-gonic/gin"

	"mychat/internal/common/cmctx"
	"mychat/internal/common/constants"
	"mychat/internal/common/errors"
	"mychat/internal/common/jwt"
	"mychat/internal/common/logger"
)

func JwtAuth(http *conf.Http, lg logger.Logger) gin.HandlerFunc {

	return func(gtx *gin.Context) {
		req := gtx.Request
		authorization := req.Header.Get(constants.HeaderAuthorization)
		if authorization == "" {
			lg.ErrorCtx(gtx, "authorization is required||authorization=%v||err=authorization is required",
				authorization)
			cmctx.ReplyJsonAPIError(gtx, &errors.TokenIsRequired)
			return
		}

		if !strings.HasPrefix(authorization, constants.HeaderAuthTokenPrefix) {
			lg.ErrorCtx(gtx, "authorization prefix is invalid||authorization=%v||err=authorization is invalid",
				authorization)
			cmctx.ReplyJsonAPIError(gtx, &errors.TokenInvalidError)
			return
		}

		token := strings.TrimPrefix(authorization, constants.HeaderAuthTokenPrefix)
		tokenClaims, err := jwt.ParseToken(token, http.JwtSecret)
		if err != nil {
			lg.ErrorCtx(gtx, "jwt.ParseToken failed||token=%v||err=%v", token, err)
			cmctx.ReplyJsonAPIError(gtx, &errors.TokenParseFailed)
			return
		}

		gtx.Request = req.WithContext(cmctx.SetCtxUserId(req.Context(), tokenClaims.UserId))

		gtx.Next()

	}
}
